package com.gu.threadPool;

import java.util.concurrent.*;

public class TestThreadPoolExecutor {

    public static void main(String[] args) {


        ExecutorService executorService = Executors.newFixedThreadPool(10);


        /**
         *  创建线程池 7 个参数
         *                               int corePoolSize,  核心线程数（一直存在，除非设置（allowCoreThreadTimeOut  允许核心线程超时）该参数）；线程池，创建好以后就准备就绪的线程数量，就等待来接受异步任务去执行
         *                               可以认为  创建好线程，并不立刻执行  new Thread();  。等待任务再去执行  start() 方法。
         *                               int maximumPoolSize,  允许最大线程数，控制资源
         *                               long keepAliveTime,   存活时间，如果当前线程数量 大于核心数量。非核心线程最大等待（新任务）时间，超时（keepAliveTime）则释放非核心线程资源（超过核心线程的一部分线程）
         *                               TimeUnit unit,   keepAliveTime 时间单位
         *                               BlockingQueue<Runnable> workQueue, 阻塞队列。 如果任务有很多，就会将目前多的任务放在队列里边。
         *                                         只要线程空闲，就会去队列里边取出新的任务继续执行。
         *                               ThreadFactory threadFactory, 线程的创建工厂
         *                               RejectedExecutionHandler handler 如果队列满了，按照指定的拒绝策略拒绝任务
         *                                      拒绝策略
         *                                          1、DiscardOldestPolicy  抛弃最老的任务，接收新来的任务
         *                                          2、AbortPolicy          抛弃新来的的任务，并抛出异常
         *                                          3、CallerRunsPolicy     不开启线程，并行执行新来的任务的run方法
         *                                          4、DiscardPolicy        抛弃新来的任务，不抛出异常
         *
         *  工作顺序:  核心，队列，新的线程，拒绝
         *  1、线程池创建，准备好core数量的核心线程，准备接收任务
         *  1.1、core满了，在将再进来的任务放入阻塞队列中，空闲的core就会自己去阻塞队列中获取任务执行
         *  1.2、阻塞队列蛮子，就直接创建新的线程执行，最大只能存在 max执行的数量。
         *  1.3、max满了就用  RejectedExecutionHandler 拒绝任务。
         *  1.4、max都执行完成，有很多空闲，在指定时间 keepAliveTime 以后，释放 （max-core）这些线程
         *
         *  一个线程池 core：7； max:20，queue:50, 100个并发进来怎么分配
         *  7个会立即执行，50个会进入队列，再开13个线程执行队列的任务，再放13个进入队列。 剩下的30个使用拒绝策略。
         *  如果不想抛弃可以使用  CallerRunsPolicy 策略，并行执行
         */
        //  LinkedBlockingDeque()
        /**
         *
         * public LinkedBlockingDeque() {
         *         this(Integer.MAX_VALUE);
         *     }
         *
         *     默认最大支持  Integer 最大值，可能导致内存不够，创建时指定数量
         */
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,
                200,
                10,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(100000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());


        /**
         * 常见几种线程池的创建方法
         */

        /**
         * 1、线程都可以回收
         * ExecutorService executorService1 = Executors.newCachedThreadPool();
         * 核心数量为 0 ，只要没任务执行就全部回收资源
         * return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
         *                                       60L, TimeUnit.SECONDS,
         *                                       new SynchronousQueue<Runnable>());
         */



        /**
         * 2、线程都不可以回收
         * ExecutorService executorService1 = Executors.newFixedThreadPool();
         * core = max 固定线程数量，常驻和最大都是传入的值
         * return new ThreadPoolExecutor(nThreads, nThreads,
         *                                       0L, TimeUnit.MILLISECONDS,
         *                                       new LinkedBlockingQueue<Runnable>());
         */

        /**
         * 3、延时一段事件后在执行任务，用于执行定时任务
         * ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool();
         * core = max 固定线程数量，常驻和最大都是传入的值
         * super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
         *               new DelayedWorkQueue());
         *
         *       核心方法
         *  long triggerTime(long delay) {
         *         return now() +
         *             ((delay < (Long.MAX_VALUE >> 1)) ? delay : overflowFree(delay));
         *     }
         */

        /**
         * 4、单线程的线程池后台从队列里获取任务挨个执行, 保证任务顺序执行
         * ExecutorService executorService1 = Executors.newSingleThreadExecutor();
         * core = max 固定线程数量，常驻和最大都是传入的值
         * return new Executors.FinalizableDelegatedExecutorService
         *                 (new ThreadPoolExecutor(1, 1,
         *                         0L, TimeUnit.MILLISECONDS,
         *                         new LinkedBlockingQueue<Runnable>()));
         */

    }
}
